home *** CD-ROM | disk | FTP | other *** search
/ T&A 2 the Maxx 3 / T and A 2 The Maxx Number 3.iso / viewers / unixview / xgiftar.z / xgiftar / pcx.c < prev    next >
C/C++ Source or Header  |  1991-05-20  |  5KB  |  212 lines

  1. /*
  2. ** pcx.c - load a ZSoft PC Paintbrush (PCX) file for use inside xloadimage
  3. **
  4. **    Tim Northrup <tim@BRS.Com>
  5. **    Adapted from code by Jef Poskanzer (see Copyright below).
  6. **
  7. **    Version 0.1 --  4/25/91 -- Initial cut
  8. **
  9. **  Copyright (c) 1991 Tim Northrup
  10. **    (see file "tgncpyrght.h" for complete copyright information)
  11. */
  12. /*
  13. ** Copyright (C) 1988 by Jef Poskanzer.
  14. **
  15. ** Permission to use, copy, modify, and distribute this software and its
  16. ** documentation for any purpose and without fee is hereby granted, provided
  17. ** that the above copyright notice appear in all copies and that both that
  18. ** copyright notice and this permission notice appear in supporting
  19. ** documentation.  This software is provided "as is" without express or
  20. ** implied warranty.
  21. **
  22. ** This program (pcxtopbm) is based on the pcx2rf program by:
  23. **   Mike Macgirvin
  24. **   Stanford Relativity Gyro Program GP-B
  25. **   Stanford, Calif. 94503
  26. **   ARPA: mike@relgyro.stanford.edu
  27. */
  28.  
  29. #include <stdio.h>
  30. #include "tgncpyrght.h"
  31. #include "image.h"
  32.  
  33. #define PCX_MAGIC 0x0a            /* first byte in a PCX image file */
  34.  
  35. static void PCX_LoadImage();        /* Routine to load a PCX file */
  36.  
  37.  
  38. /*
  39. **  pcxIdent
  40. **
  41. **    Identify passed file as a PC Paintbrush image or not
  42. **
  43. **    Returns 1 if file is a PCX file, 0 otherwise
  44. */
  45.  
  46. unsigned int pcxIdent(fullname, name)
  47.  
  48. char *fullname, *name;
  49. {
  50.     ZFILE *zf;
  51.     unsigned int  ret;
  52.     int xmin;
  53.     int xmax;
  54.     int ymin;
  55.     int ymax;
  56.     unsigned char pcxhd[128];
  57.  
  58.     ret = 0;
  59.  
  60.     if (! (zf = zopen(fullname)))
  61.         return(0);
  62.  
  63.     /* Read .pcx header. */
  64.     if (zread(zf,pcxhd,128) == 128) {
  65.         if (pcxhd[0] == PCX_MAGIC) {
  66.             /* Calculate raster header and swap bytes. */
  67.             xmin = pcxhd[4] + ( 256 * pcxhd[5] );
  68.             ymin = pcxhd[6] + ( 256 * pcxhd[7] );
  69.             xmax = pcxhd[8] + ( 256 * pcxhd[9] );
  70.             ymax = pcxhd[10] + ( 256 * pcxhd[11] );
  71.             xmax = xmax - xmin + 1;
  72.             ymax = ymax - ymin + 1;
  73.  
  74.             printf("%s is a %dx%d PC Paintbrush image\n",
  75.                 name,xmax,ymax);
  76.             ret = 1;
  77.             }
  78.         }
  79.  
  80.     zclose(zf);
  81.  
  82.     return(ret);
  83. }
  84.  
  85.  
  86. /*
  87. **  pcxLoad
  88. **
  89. **    Load PCX Paintbrush file into an Image structure.
  90. **
  91. **    Returns pointer to allocated struct if successful, NULL otherwise
  92. */
  93.  
  94. Image *pcxLoad (fullname,name,verbose)
  95.  
  96. char *fullname, *name;
  97. unsigned int verbose;
  98. {
  99.     ZFILE *zf;
  100.     unsigned char pcxhd[128];
  101.     int cnt, b;
  102.     int xmin;
  103.     int xmax;
  104.     int ymin;
  105.     int ymax;
  106.     int bytes_per_row;
  107.     register Image *image;
  108.  
  109.     /* Open input file. */
  110.     if ( ! (zf = zopen(fullname)))
  111.         return((Image *)NULL);
  112.  
  113.     /* Read .pcx header. */
  114.     if (zread(zf,pcxhd,128) != 128) {
  115.         zclose(zf);
  116.         return((Image *)NULL);
  117.         }
  118.  
  119.     if ((pcxhd[0] != PCX_MAGIC) || (pcxhd[1] > 5)) {
  120.         zclose(zf);
  121.         return((Image *)NULL);
  122.         }
  123.  
  124.     if (pcxhd[65] > 1) {
  125.         printf("Unable to handle Color PCX image\n");
  126.         return((Image *)NULL);
  127.         }
  128.  
  129.     /* Calculate raster header and swap bytes. */
  130.     xmin = pcxhd[4] + ( 256 * pcxhd[5] );
  131.     ymin = pcxhd[6] + ( 256 * pcxhd[7] );
  132.     xmax = pcxhd[8] + ( 256 * pcxhd[9] );
  133.     ymax = pcxhd[10] + ( 256 * pcxhd[11] );
  134.     xmax = xmax - xmin + 1;
  135.     ymax = ymax - ymin + 1;
  136.     bytes_per_row = pcxhd[66] + ( 256 * pcxhd[67] );
  137.  
  138.     if (verbose)
  139.         printf("%s is a %dx%d PC Paintbrush image\n",name,xmax,ymax);
  140.     znocache(zf);
  141.  
  142.     /* Allocate pbm array. */
  143.     image = newBitImage(xmax,ymax);
  144.  
  145.     /* Read compressed bitmap. */
  146.     PCX_LoadImage( zf, bytes_per_row, image, ymax );
  147.     zclose( zf );
  148.  
  149.     image->title = dupString(name);
  150.  
  151.     return(image);
  152. }
  153.  
  154.  
  155. /*
  156. **  PCX_LoadImage
  157. **
  158. **    Load PC Paintbrush file into the passed Image structure.
  159. **
  160. **    Returns no value (void function)
  161. */
  162.  
  163. static void PCX_LoadImage (zf,bytes_per_row,image,rows)
  164.  
  165.     ZFILE *zf;
  166.     int bytes_per_row;
  167.     Image *image;
  168.     int rows;
  169. {
  170.     /* Goes like this: Read a byte.  If the two high bits are set,
  171.     ** then the low 6 bits contain a repeat count, and the byte to
  172.     ** repeat is the next byte in the file.  If the two high bits are
  173.     ** not set, then this is the byte to write.
  174.     */
  175.  
  176.     register unsigned char *ptr;
  177.     int row = 0;
  178.     int bytes_this_row = 0;
  179.     int b, i, cnt;
  180.  
  181.     ptr = &(image->data[0]);
  182.  
  183.     while ((b = zgetc(zf)) != EOF) {
  184.  
  185.         if ((b & 0xC0) == 0xC0) {
  186.             /* have a repetition count -- mask flag bits */
  187.             cnt = b & 0x3F;
  188.             b = zgetc(zf);
  189.             if (b == EOF)
  190.                 printf("Error in PCX file: unexpected EOF\n");
  191.             }
  192.         else {
  193.             cnt = 1;        /* no repeating this one */
  194.             }
  195.  
  196.         for ( i = 0; i < cnt; i++ ) {
  197.             if ( row >= rows ) {
  198.                 printf("Warning: junk after bitmap data ignored\n");
  199.                 return;
  200.                 }
  201.             *ptr++ = (unsigned char) (255 - b);
  202.             if (++bytes_this_row == bytes_per_row) {
  203.                 /* start of a new line */
  204.                 row++;
  205.                 bytes_this_row = 0;
  206.                 }
  207.             }
  208.         }
  209.  
  210.     return;
  211. }
  212.